const { Middleware } = require("springbreeze"), //modify .
    delegate = require("delegates"),
    Redis = require("redis"),
    BlueBird = require("bluebird")

BlueBird.promisifyAll(Redis)

module.exports = class RedisMiddleware extends Middleware {

    constructor() {
        super()
    }

    before() {

    }

    async start() {
        const config = this.config()
        if (config) {
            /**
             *  host 
             *  port 
             *  password 
             *  db
             *  ....其他参考Api
             *      https://github.com/NodeRedis/node_redis
             */
            this.redis = Redis.createClient(config)
            this.after()
        }
    }

    after() {
        // //将redis所有的方法代理到middleware上
        delegate(this, "redis")
            .method("set")
            // .method("setAsync")
            .method("get")
            // .method("getAsync")
            .method("del").method("delAsync")
            .method("incrby").method("incrbyAsync")
            .method("decrby").method("decrbyAsync")
            .method("incrbyfloat").method("incrbyfloatAsync")
            .method("append").method("appendAsync")
            .method("getrange").method("getrangeAsync")
            .method("setrange").method("setrangeAsync")
            .method("rpush").method("rpushAsync")
            .method("lrange").method("lrangeAsync")
            .method("lindex").method("lindexAsync")
            .method("lpop").method("lpopAsync")
            .method("rpop").method("rpopAsync")
            .method("ltrim").method("ltrimAsync")
            .method("sadd").method("saddAsync")
            .method("smembers").method("smembersAsync")
            .method("sismenber").method("sismenberAsync")
            .method("srem").method("sremAsync")
            .method("scad").method("scadAsync")
            .method("spop").method("spopAsync")
            .method("smove").method("smoveAsync")
            .method("sdiff").method("sdiffAsync")
            .method("sdiffstore").method("sdiffstoreAsync")
            .method("sinter").method("sinterAsync")
            .method("sinterstore").method("sinterstoreAsync")
            .method("sunion").method("sunionAsync")
            .method("sunionstore").method("sunionstoreAsync")
            .method("hset").method("hsetAsync")
            .method("hget").method("hgetAsync")
            .method("hgetall").method("hgetallAsync")
            .method("hdel").method("hdelAsync")
            .method("hmset").method("hmsetAsync")
            .method("hmget").method("hmgetAsync")
            .method("hlen").method("hlenAsync")
            .method("hexists").method("hexistsAsync")
            .method("hkeys").method("hkeysAsync")
            .method("hvals").method("hvalsAsync")
            .method("hincrby").method("hincrbyAsync")
            .method("hincrbyfloat").method("hincrbyfloatAsync")
            .method("zadd").method("zaddAsync")
            .method("zrange").method("zrangeAsync")
            .method("zrangebyscore").method("zrangebyscoreAsync")
            .method("zrem").method("zremAsync")
            .method("zcard").method("zcardAsync")
            .method("del").method("delAsync")
            .method("exists").method("existsAsync")
            .method("expire").method("expireAsync")
            .method("pexpire").method("pexpireAsync")
            .method("expireat").method("expireatAsync")
            .method("pexpireat").method("pexpireatAsync")
            .method("persist").method("persistAsync")
            .method("sort").method("sortAsync")
            .method("flushdb").method("flushdbAsync")
    }

    format( v ){
        if( typeof( v ) == "object")
            return JSON.stringify( v )
        return v 
    }

    parse( v ){
        try{
            return JSON.parse( v )
        }catch(e){
            return v
        }
    }

    async setAsync( key , value ,exipre ){
        value = this.format( value )
        const result = this.redis.setAsync(key , value )
        if( exipre > 0 )  {
            this.redis.expire( key , exipre)
        } 
        return result
    }

    async getAsync( key ){
        const v = await this.redis.getAsync( key ) 
        return this.parse( v )
    }

}

// const keys = ["set", "get", "del", "incrby", "decrby", "incrbyfloat", "append"
//     , "getrange", "setrange", "rpush", "lrange", "lindex", "lpop"
//     , "rpop", "ltrim", "sadd", "smembers", "sismenber", "srem", "scad", "spop"
//     , "smove", "sdiff", "sdiffstore", "sinter"
//     , "sinterstore", "sunion", "sunionstore", "hset", "hget", "hgetall", "hdel"
//     , "hmset", "hmget", "hlen", "hexists", "hkeys", "hvals", "hincrby", "hincrbyfloat"
//     , "zadd", "zrange", "zrangebyscore", "zrem", "zcard", "del", "exists"
//     , "expire", "pexpire", "expireat", "pexpireat", "persist", "sort", "flushdb"]

// let output = ""
// for (let idx in keys) {
//     const key = keys[idx]
//     output += '.method("' + key + '").method("' + key + 'Async")\n'
// }

// console.log(output)


